home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / Hierarchical Lists / Src / EnumerateHFSCatalog.c next >
Encoding:
C/C++ Source or Header  |  1994-03-16  |  3.9 KB  |  121 lines  |  [TEXT/KAHL]

  1. /*                                EnumerateHFSCatalog.c                            */
  2. /*
  3.  * List In A List Sample
  4.  * EnumerateHFSCatalog.c
  5.  * Copyright © 1993-94 Apple Computer Inc.
  6.  *
  7.  * EnumerateHFSCatalog is a recursive function that scans an HFS file directory,
  8.  * building a list of the file and folder names in a hierarchical list. It is
  9.  * interesting only as an example of how to use the hierarchical list functions.
  10.  */
  11. #include "ListInAList.h"
  12. #include <Files.h>
  13.  
  14. /*
  15.  * EnumerateHFSCatalog
  16.  * Enumerate the HFS at this level. To enumerate a volume, clear the hierarchical
  17.  * list and call EnumerateHFSCatalog with the following parameters:
  18.  *        theList                    the hierarchical list
  19.  *        volumeRefNum            volume to catalog
  20.  *        volumeDirIndex            fsRtDirID: the root directory
  21.  *        indentLevel                zero
  22.  * Each call to EnumerateHFSCatalog builds a sub-list. When the function finds a
  23.  * folder, it calls itself recursively with the folder's volumeDirIndex and an
  24.  * incremented indentLevel. EnumerateHFSCatalog returns the index of the first
  25.  * element (i.e., the first file or folder in the directory it enumerated). This
  26.  * is stored in the subElement of the parent list.
  27.  *
  28.  * This is not a good algorithm design as it will evaluate the entire disk before
  29.  * processing events. This means that the user cannot interrupt the application and
  30.  * that other parts of the system will not run. Since the Macintosh requires
  31.  * "cooperative multitasking," a production program should be organized so that
  32.  * this evaluation takes place during idle time in the event loop. To minimize
  33.  * this problem (for debugging), we call Button each time through the loop and
  34.  * stop if the user clicks on the mouse.
  35.  */
  36. TwistDownHdl
  37. EnumerateHFSCatalog(
  38.         ListHandle                    theList,
  39.         short                        indentLevel,
  40.         short                        volumeRefNum,
  41.         long                        volumeDirIndex
  42.     )
  43. {
  44.         HFileInfo                    pb;
  45.         Str255                        fileName;
  46.         OSErr                        status;
  47.         short                        dirIndex;
  48.         TwistDownHdl                previousElement;
  49.         TwistDownHdl                thisElement;
  50.         TwistDownHdl                firstElement;
  51.         EventRecord                    currentEvent;
  52.         Str255                        windowTitle;
  53.         Str15                        depthString;
  54. #define ELEM    (**thisElement)
  55. #define FLAG    (ELEM.flag)
  56.  
  57.         /*
  58.          * Fiddle the window title to show progress.
  59.          */
  60.         pstrcpy(windowTitle, "\pFolder depth: ");
  61.         NumToString(indentLevel, (StringPtr) &depthString);
  62.         pstrcat(windowTitle, depthString);
  63.         pstrcat(windowTitle, "\p - Click to stop");
  64.         SetWTitle(FrontWindow(), windowTitle);
  65.         /* */
  66.         Clear(pb);
  67.         pb.ioNamePtr = fileName;
  68.         pb.ioVRefNum = volumeRefNum;
  69.         dirIndex = 1;
  70.         firstElement = NULL;
  71.         previousElement = NULL;
  72.         /*
  73.          * This loop scans the volume for all directories and files. The loop
  74.          * exits on error (i.e., no more files) or when the user clicks on
  75.          * the mouse.
  76.          */
  77.         do {
  78.             /*
  79.              * Call EventAvail every time through this loop so that background
  80.              * programs get time to get some work done.
  81.              */
  82.             EventAvail(everyEvent, ¤tEvent);
  83.             SpinCursor();
  84.             pb.ioFDirIndex = dirIndex;
  85.             pb.ioDirID = volumeDirIndex;
  86.             status = PBGetCatInfo((CInfoPBPtr) &pb, SYNC);
  87.             if (status == noErr) {
  88.                 status = MakeTwistDownElement(
  89.                         previousElement,
  90.                         indentLevel,
  91.                         fileName[0],
  92.                         (Ptr) &fileName[1],
  93.                         &thisElement
  94.                     );
  95.             }
  96.             if (status == noErr) {
  97.                 if (firstElement == NULL)
  98.                     firstElement = thisElement;
  99.                 /*
  100.                  * If this is a folder, descend the hierarchy by calling ourselves
  101.                  * recursively. Store the first element in the new sub-list
  102.                  * into our subElement pointer. Note that FLAG.hasTwistDown will
  103.                  * be TRUE even if there are no files in the sub-folder.
  104.                  */
  105.                 if ((pb.ioFlAttrib & ioDirMask) == ioDirMask) {
  106.                     ELEM.flag |= kHasTwistDown;
  107.                     ELEM.subElement = EnumerateHFSCatalog(
  108.                             theList,
  109.                             indentLevel + 1,
  110.                             volumeRefNum,
  111.                             pb.ioDirID
  112.                         );
  113.                 }
  114.                 ++dirIndex;
  115.                  previousElement = thisElement;    /* Set linkage for next file    */
  116.             }
  117.         } while (status == noErr && Button() == FALSE);
  118.         return (firstElement);
  119. }        
  120.             
  121.